package com.hemj.fileInfo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hemj.common.exception.ServiceException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import com.hemj.common.utils.SecurityUtils;
import com.hemj.common.utils.StringUtils;
import com.hemj.common.utils.file.FileUtils;
import com.hemj.fileInfo.bo.FileTreeSelect;
import com.hemj.fileInfo.domain.FileInfoLog;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hemj.fileInfo.mapper.FileInfoMapper;
import com.hemj.fileInfo.domain.FileInfo;
import com.hemj.fileInfo.service.IFileInfoService;
import com.hemj.common.utils.IdGenerator.IdGeneratorFactory;
import com.hemj.fileInfo.vo.FileInfoVo;
import com.hemj.fileInfo.bo.FileInfoBo;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 文件Service业务层处理
 * 
 * @author hemj
 * @date 2024-09-13
 */
@Service
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements IFileInfoService
{
    @Autowired
    private IdGeneratorFactory idGeneratorFactory;
    @Autowired
    private FileInfoLogServiceImpl fileInfoLogService;
    
    /**
         * 验证参数
         */
    private void validateData(FileInfo fileInfo){

    }

    public void setView(Long id) {
        FileInfo fileInfo = this.getById(id);
        if (ObjectUtils.isEmpty(fileInfo.getViewNum())){
            fileInfo.setViewNum(1);
        }else {
            fileInfo.setViewNum(fileInfo.getViewNum() + 1);
        }
        this.updateById(fileInfo);
    }


    /**
     * 保存数据
     */
    @Transactional(timeout = 3000, isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED)
    public String saveCascade(FileInfoVo jsonObject){
        if (ObjectUtils.isEmpty(jsonObject.getUrl())){
            throw new ServiceException("请选择文件！");
        }
        String[] urls = jsonObject.getUrl().split(",");
        List<FileInfo> fileInfos = new ArrayList<>();
        List<FileInfoLog> fileInfoLogs = new ArrayList<>();
        String nickName = SecurityUtils.getLoginUser().getUsername();
        int num = 0;
        for (String url : urls) {
            num++;
            FileInfo fileInfo = new FileInfo();
            fileInfo.setId(idGeneratorFactory.getId(FileInfo.class.getSimpleName()));
            fileInfo.setUrl(url);
            String filename = FileUtils.getName(url);
            if (!ObjectUtils.isEmpty(jsonObject.getName())){
                if (num > 1 || urls.length>1){
                    fileInfo.setName(jsonObject.getName()+"-"+num);
                }else {
                    fileInfo.setName(jsonObject.getName());
                }
            }else {
                fileInfo.setName(filename);
            }
            fileInfo.setType(FileUtils.getFileExtension(filename));
            fileInfo.setSize(FileUtils.getFileSize(url));
            fileInfo.setRemark(jsonObject.getRemark());
            fileInfo.setSeqNo(jsonObject.getSeqNo());
            fileInfo.setViewNum(0);
            Long parentId = jsonObject.getParentId();
            if (!ObjectUtils.isEmpty(parentId) && parentId != 0){
                FileInfo fileParent = this.getById(parentId);
                fileInfo.setAncestors(fileParent.getAncestors()+fileParent.getId()+",");
                fileInfo.setParentId(parentId);
            }else {
                fileInfo.setParentId(0l);
                fileInfo.setAncestors("0,");
            }
            fileInfo.setCreateBy(nickName);
            fileInfo.setCreateTime(new Date());
            fileInfos.add(fileInfo);
            FileInfoLog fileInfoLog = new FileInfoLog();
            BeanUtils.copyProperties(fileInfo, fileInfoLog);
            fileInfoLog.setId(idGeneratorFactory.getId(FileInfoLog.class.getSimpleName()));
            fileInfoLogs.add(fileInfoLog);
        }
        this.saveBatch(fileInfos);
        fileInfoLogService.saveBatch(fileInfoLogs);
        return "OK";
    }

    @Transactional(timeout = 3000, isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED)
    public String addFolder(FileInfoVo jsonObject){
        FileInfo fileInfo = new FileInfo();
        fileInfo.setId(idGeneratorFactory.getId(FileInfo.class.getSimpleName()));
        fileInfo.setName(jsonObject.getName());
        fileInfo.setType("folder");
        fileInfo.setRemark(jsonObject.getRemark());
        fileInfo.setCreateBy(SecurityUtils.getUsername());
        fileInfo.setCreateTime(new Date());
        fileInfo.setSeqNo(jsonObject.getSeqNo());
        fileInfo.setViewNum(0);
        Long parentId = jsonObject.getParentId();
        if (!ObjectUtils.isEmpty(parentId) && parentId != 0){
            FileInfo fileParent = this.getById(parentId);
            fileInfo.setAncestors(fileParent.getAncestors()+fileParent.getId()+",");
            fileInfo.setParentId(parentId);
        }else {
            fileInfo.setParentId(0l);
            fileInfo.setAncestors("0,");
        }
        this.save(fileInfo);
        return "OK";
    }


    /**
     * 编辑数据
     */
    @Transactional(timeout = 3000, isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED)
    public FileInfo updateCascade(FileInfoVo jsonObject){
        FileInfo fileInfo = this.getById(jsonObject.getId());;
        fileInfo.setName(jsonObject.getName());
        fileInfo.setRemark(jsonObject.getRemark());
        fileInfo.setSeqNo(jsonObject.getSeqNo());
        Long parentId = jsonObject.getParentId();
        if (!ObjectUtils.isEmpty(parentId) && parentId != 0){
            FileInfo fileParent = this.getById(parentId);
            fileInfo.setAncestors(fileParent.getAncestors()+fileParent.getId()+",");
            fileInfo.setParentId(parentId);
        }else {
            fileInfo.setParentId(0l);
            fileInfo.setAncestors("0,");
        }
        this.updateById(fileInfo);
        return fileInfo;
    }


    /**
     * 构建前端所需要树结构
     *
     * @param depts 部门列表
     * @return 树结构列表
     */
    public List<FileInfoBo> buildFolderTree(List<FileInfoBo> depts)
    {
        List<FileInfoBo> returnList = new ArrayList<FileInfoBo>();
        List<Long> tempList = new ArrayList<Long>();
        for (FileInfoBo dept : depts)
        {
            tempList.add(dept.getId());
        }
        for (FileInfoBo dept : depts)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId()))
            {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = depts;
        }
        return returnList;
    }


    public List<FileTreeSelect> buildFolderTreeSelect(List<FileInfoBo> depts)
    {
        List<FileInfoBo> deptTrees = buildFolderTree(depts);
        return deptTrees.stream().map(FileTreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<FileInfoBo> list, FileInfoBo t)
    {
        // 得到子节点列表
        List<FileInfoBo> childList = getChildList(list, t);
        t.setChildren(childList);
        for (FileInfoBo tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }


    /**
     * 得到子节点列表
     */
    private List<FileInfoBo> getChildList(List<FileInfoBo> list, FileInfoBo t)
    {
        List<FileInfoBo> tlist = new ArrayList<FileInfoBo>();
        Iterator<FileInfoBo> it = list.iterator();
        while (it.hasNext())
        {
            FileInfoBo n = (FileInfoBo) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<FileInfoBo> list, FileInfoBo t)
    {
        return getChildList(list, t).size() > 0;
    }




    /**
     * 初始化查询条件
     */
    public LambdaQueryWrapper<FileInfo> initQueryWrapper(FileInfoVo jsonObject){
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        if (!ObjectUtils.isEmpty(jsonObject.getId())) {
        }
        if (!ObjectUtils.isEmpty(jsonObject.getParentId())) {
            queryWrapper.eq(FileInfo::getParentId, jsonObject.getParentId());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getAncestors())) {
            queryWrapper.like(FileInfo::getAncestors, jsonObject.getAncestors());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getName())) {
            queryWrapper.like(FileInfo::getName, jsonObject.getName());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getType())) {
            queryWrapper.eq(FileInfo::getType, jsonObject.getType());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getNotType())) {
            queryWrapper.ne(FileInfo::getType, jsonObject.getNotType());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getCreateBy())) {
        }
        if (!ObjectUtils.isEmpty(jsonObject.getCreateTime())) {
        }
        if (!ObjectUtils.isEmpty(jsonObject.getUpdateBy())) {
        }
        if (!ObjectUtils.isEmpty(jsonObject.getUpdateTime())) {
        }
        if (!ObjectUtils.isEmpty(jsonObject.getTypes())) {
            queryWrapper.in(FileInfo::getType, jsonObject.getTypes());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getNotTypes())) {
            queryWrapper.notIn(FileInfo::getType, jsonObject.getNotTypes());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getUrl())) {
            queryWrapper.eq(FileInfo::getUrl, jsonObject.getUrl());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getSize())) {
            queryWrapper.eq(FileInfo::getSize, jsonObject.getSize());
        }
        if (!ObjectUtils.isEmpty(jsonObject.getFileIds())) {
            queryWrapper.in(FileInfo::getId, jsonObject.getFileIds());
        }
        queryWrapper.orderByAsc(FileInfo::getSeqNo);
        return queryWrapper;
    }

    /**
     * list查询
     */
    public List<FileInfoBo> queryList(FileInfoVo jsonObject) {
        List<FileInfo> fileInfos = this.list(initQueryWrapper(jsonObject));
        List<FileInfoBo> bos = new ArrayList<>();
        for (FileInfo fileInfo:fileInfos) {
            FileInfoBo fileInfoBo = new FileInfoBo();
            BeanUtils.copyProperties(fileInfo,fileInfoBo);
            bos.add(fileInfoBo);
        }
        return bos;
    }

    public List<FileInfoBo> hotList(FileInfoVo jsonObject) {
        LambdaQueryWrapper<FileInfo> wrapper = initQueryWrapper(jsonObject);
        wrapper.orderByDesc(FileInfo::getViewNum);
        List<FileInfo> fileInfos = this.list(wrapper);
        List<FileInfoBo> bos = new ArrayList<>();
        for (FileInfo fileInfo:fileInfos) {
            FileInfoBo fileInfoBo = new FileInfoBo();
            BeanUtils.copyProperties(fileInfo,fileInfoBo);
            bos.add(fileInfoBo);
        }
        return bos;
    }

    /**
     * 统计
     */
    public long countList(FileInfoVo jsonObject) {
        return this.count(initQueryWrapper(jsonObject));
    }

    /**
     * 获取单个数据
     */
    public FileInfoBo getOneById(Long id){
        FileInfo fileInfo = this.getById(id);
        FileInfoBo fileInfoBo = new FileInfoBo();
        BeanUtils.copyProperties(fileInfo,fileInfoBo);
        if (!ObjectUtils.isEmpty(fileInfo.getParentId()) && fileInfoBo.getParentId() != 0){
            FileInfo fileInfoP = this.getById(fileInfo.getParentId());
            if (!ObjectUtils.isEmpty(fileInfo)){
                fileInfoBo.setParentName(fileInfoP.getName());
            }
        }
        return fileInfoBo;
    }



}
